﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Net.Mail;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ProfileTraffic")]
	public class ProfileTrafficController : BaseDbController
	{
		public ActionResult Index()
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			return View();
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ProfileHotelModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = from profileTrafficInfo in DbContext.ProfileTrafficInfo.AsNoTracking()
					.Where(x => x.Creator == LoginUser.UserName)
				  group profileTrafficInfo by new { conferenceId = profileTrafficInfo.ConferenceId, OrderNum = profileTrafficInfo.OrderNum } into g
				  join conferenceMaster in DbContext.ConferenceMaster.AsNoTracking()
					on g.Key.conferenceId equals conferenceMaster.ID
				  orderby g.Key.OrderNum descending
				  select new
				  {
					  Status = g.Max(x => x.Status),
					  Currency = g.Max(x => x.Currency),
					  Fee = g.Sum(x => x.Fee),

					  ConferenceId = g.Key.conferenceId,
					  OrderNum = g.Key.OrderNum,
					  Remark = g.Max(x => x.Remark),
					  Contact = g.Max(x => x.FullName),
					  ContactMobile = g.Max(x => x.Mobile),
					  ContactMail = g.Max(x => x.Mail),
					  ConferenceName = conferenceMaster.ConferenceName,
					  CreateDate = g.Max(x => x.CreateDate),
					  HomePageUrl = conferenceMaster.HomePageUrl,
					  ConferenceNickName = conferenceMaster.ConferenceNickName,
					  BenefitStartDate = conferenceMaster.BenefitStartDate,
					  BenefitEndDate = conferenceMaster.BenefitEndDate
				  };

			if (!string.IsNullOrWhiteSpace(model.ConferenceName) && model.ConferenceName != "")
			{
				sql = sql.Where(x => x.ConferenceName.Contains(model.ConferenceName));
			}


			int total = await sql.CountAsync();
			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.CreateDate).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Status = x.Status == ConstValues.Status.已预订 ? Resources.HasBooked : Resources.ScheduleStatusCancel,
				Currency = x.Currency,
				ConferenceId = x.ConferenceId,
				OrderNum = x.OrderNum,
				Remark = x.Remark,
				Contact = x.Contact,
				ContactMobile = x.ContactMobile,
				ContactMail = x.ContactMail,
				ConferenceName = x.ConferenceName,
				CreateDate = x.CreateDate,
				HomePageUrl = x.HomePageUrl,
				ConferenceNickName = x.ConferenceNickName,
				TotalFee = x.Fee.ToString("N2")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetBookingDetail(string orderNum)
		{
			var sql = from profileTrafficInfo in DbContext.ProfileTrafficInfo.AsNoTracking()
					.Where(x => x.OrderNum == orderNum)
				  join conferenceMaster in DbContext.ConferenceMaster.AsNoTracking()
					 on profileTrafficInfo.ConferenceId equals conferenceMaster.ID
				  join trafficMaster in DbContext.TrafficMaster.AsNoTracking()
					 on profileTrafficInfo.TrafficId equals trafficMaster.ID into t1
				  from traffic in t1.DefaultIfEmpty()
				  orderby profileTrafficInfo.FlightDate descending
				  select new
				  {
					  Id = profileTrafficInfo.ID,
					  TrafficId = profileTrafficInfo.TrafficId,
					  Status = profileTrafficInfo.Status,
					  Currency = profileTrafficInfo.Currency,
					  Fee = profileTrafficInfo.Fee,
					  FlightDate = profileTrafficInfo.FlightDate,
					  FlightNum = profileTrafficInfo.FlightNum,
					  BenefitStartDate = conferenceMaster.BenefitStartDate,
					  BenefitEndDate = conferenceMaster.BenefitEndDate,
					  IsInternational = conferenceMaster.IsInternational,
					  conferenceId = conferenceMaster.ID,
					  TrafficName = traffic.TrafficName,
					  TrafficType = profileTrafficInfo.TrafficType,
					  Price = traffic.Price
				  };
			int total = await sql.CountAsync();
			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.Id,
				Status = x.Status == ConstValues.Status.已预订 ? Resources.HasBooked : Resources.ScheduleStatusCancel,
				Currency = x.Currency,
				FlightDate = x.IsInternational ?
						x.FlightDate.ToString("MM/dd/yyyy HH:mm") :
						x.FlightDate.ToString("yyyy-MM-dd HH:mm"),
				FlightNum = x.FlightNum,
				TrafficType = Utility.ChangeTrafficTypeToResources(x.TrafficType),
				TrafficName = x.TrafficName,
				Price = x.Price.Value,
				conferenceId = x.conferenceId
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> AddTraffic(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = DbContext.ProfileTrafficInfo.AsNoTracking()
					.FirstOrDefault(x => x.OrderNum == model.OrderNumber);
			List<Traffic> mailList = new List<Traffic>();

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				model.TrafficList.ForEach(x =>
				{
					var trafficMaster = DbContext.TrafficMaster.AsNoTracking()
							.FirstOrDefault(y => y.ID == x.TrafficId);

					var profileTrafficInfo = new ProfileTrafficInfo
					{
						ID = Utility.GetTableId(ConstValues.TableName.ProfileTrafficInfo),
						UserName = LoginUser.UserName,
						ConferenceId = model.ConferenceId,
						TrafficId = x.TrafficId,
						TrafficType = x.TrafficType,
						FlightDate = Convert.ToDateTime(x.FlightDate),
						FlightNum = x.FlightNum.Trim(),
						Remark = x.Remark.Trim(),
						FullName = x.ContactName.Trim(),
						Mail = x.ContactMail.Trim(),
						Mobile = x.ContactMobile.Trim(),
						Fee = trafficMaster.Price.Value,
						Currency = trafficMaster.Currency,
						Creator = LoginUser.UserName,
						CreateDate = DateTime.Now,
						CreateIP = LoginUser.IP,
						OrderNum = result.OrderNum,
						Status = ConstValues.Status.已预订
					};
					DbContext.ProfileTrafficInfo.Add(profileTrafficInfo);

					var mailTraffic = new Traffic()
					{
						TrafficType = x.TrafficType,
						FlightDate = x.FlightDate,
						FlightNum = x.FlightNum,
						TrafficName = trafficMaster.TrafficName
					};
					mailList.Add(mailTraffic);
				});
				await DbContext.SaveChangesAsync();

				#region SendMail
				var conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
						.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
							x.MailType == ConstValues.MailType.酒店交通服务邮箱 &&
							x.ConferenceId == model.ConferenceId);

				if (conferenceMailServerMaster == null)
				{
					conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
								x.MailType == ConstValues.MailType.会议邮箱 &&
								x.ConferenceId == model.ConferenceId);
				}

				if (conferenceMailServerMaster != null)
				{
					MailSender sender = new MailSender(conferenceMailServerMaster.MailServer);
					MailAddress from = new MailAddress(conferenceMailServerMaster.Mail);
					MailAddress to = new MailAddress(conferenceMailServerMaster.Mail);

					MailMessage message = Utility.GetMailContent(new MailModel
					{
						MailRemark = ConstValues.MailSubject.交通修改,
						Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn,
						ConferenceId = conferenceMaster.ID,
						OrderNum = model.OrderNumber,
						TrafficStatus = conferenceMaster.IsInternational ? "Reserved" : "已预订",
						TrafficList = mailList
					});
					message.To.Add(to);

					if (!string.IsNullOrWhiteSpace(conferenceMailServerMaster.CcMail))
					{
						foreach (string cc in conferenceMailServerMaster.CcMail.Split(ConstValues.chrSemicolon))
						{
							if (!string.IsNullOrWhiteSpace(cc) && cc.Contains(ConstValues.chrAt))
							{
								message.Bcc.Add(new MailAddress(cc.Trim()));
							}
						}
					}

					var mailTask = Task.Run(() =>
					{
						sender.SendMail(from, message, conferenceMailServerMaster.Password);
					});
				}
				#endregion

				transaction.Commit();
			};

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> EditTraffic(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var isTrue = true;
			List<Traffic> mailList = new List<Traffic>();

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				model.TrafficList.ForEach(x =>
				{
					var result = DbContext.ProfileTrafficInfo.FirstOrDefault(y => y.ID == model.ProfileTrafficId);
					if (result == null)
					{
						isTrue = false;
					}

					var trafficMaster = DbContext.TrafficMaster.AsNoTracking()
							.FirstOrDefault(y => y.ID == x.TrafficId);

					result.TrafficId = x.TrafficId;
					result.FlightDate = Convert.ToDateTime(x.FlightDate);
					result.FlightNum = x.FlightNum.Trim();
					result.Remark = x.Remark.Trim();
					result.FullName = x.ContactName.Trim();
					result.Mail = x.ContactMail.Trim();
					result.Mobile = x.ContactMobile.Trim();
					result.Fee = trafficMaster.Price.Value;
					result.Currency = trafficMaster.Currency;

					var mailTraffic = new Traffic()
					{
						TrafficType = x.TrafficType,
						FlightDate = x.FlightDate,
						FlightNum = x.FlightNum,
						TrafficName = trafficMaster.TrafficName
					};
					mailList.Add(mailTraffic);
				});			

				if (isTrue)
				{
					await DbContext.SaveChangesAsync();

					#region SendMail
					var conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
								x.MailType == ConstValues.MailType.酒店交通服务邮箱 &&
								x.ConferenceId == model.ConferenceId);

					if (conferenceMailServerMaster == null)
					{
						conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
								.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
									x.MailType == ConstValues.MailType.会议邮箱 &&
									x.ConferenceId == model.ConferenceId);
					}

					if (conferenceMailServerMaster != null)
					{
						MailSender sender = new MailSender(conferenceMailServerMaster.MailServer);
						MailAddress from = new MailAddress(conferenceMailServerMaster.Mail);
						MailAddress to = new MailAddress(conferenceMailServerMaster.Mail);

						MailMessage message = Utility.GetMailContent(new MailModel
						{
							MailRemark = ConstValues.MailSubject.交通修改,
							Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn,
							ConferenceId = conferenceMaster.ID,
							OrderNum = model.OrderNumber,
							TrafficStatus = conferenceMaster.IsInternational ? "Reserved" : "已预订",
							TrafficList = mailList
						});
						message.To.Add(to);

						if (!string.IsNullOrWhiteSpace(conferenceMailServerMaster.CcMail))
						{
							foreach (string cc in conferenceMailServerMaster.CcMail.Split(ConstValues.chrSemicolon))
							{
								if (!string.IsNullOrWhiteSpace(cc) && cc.Contains(ConstValues.chrAt))
								{
									message.Bcc.Add(new MailAddress(cc.Trim()));
								}
							}
						}

						var mailTask = Task.Run(() =>
						{
							sender.SendMail(from, message, conferenceMailServerMaster.Password);
						});
					}
					#endregion

					transaction.Commit();
				}
			}

			if (isTrue)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetTrafficDetail(string id)
		{
			var data = await DbContext.ProfileTrafficInfo.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (data != null)
			{
				var result = new
				{
					FlightNum = data.FlightNum,
					FlightDate = data.Currency == ConstValues.Currency.美元 ?
						data.FlightDate.ToString("MM/dd/yyyy HH:ss") :
						data.FlightDate.ToString("yyyy-MM-dd HH:ss"),
					Fee = data.Fee,
					TrafficId = data.TrafficId,
					Currency = data.Currency,
					ConferenceId = data.ConferenceId,
					FullName = data.FullName,
					Mail = data.Mail,
					Mobile = data.Mobile,
					Remark = data.Remark
				};

				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> CancelBooking(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ProfileTrafficInfo
					.FirstOrDefaultAsync(x => x.ID == model.ProfileTrafficId);

			if (result == null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}

			result.Status = ConstValues.Status.已取消;
			await DbContext.SaveChangesAsync();

			var trafficMaster = DbContext.TrafficMaster.AsNoTracking()
					.FirstOrDefault(x => x.ID == result.TrafficId);

			#region SendMail
			var conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.MailType == ConstValues.MailType.酒店交通服务邮箱 &&
						x.ConferenceId == model.ConferenceId);

			if (conferenceMailServerMaster == null)
			{
				conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
						.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
							x.MailType == ConstValues.MailType.会议邮箱 &&
							x.ConferenceId == model.ConferenceId);
			}

			if (conferenceMailServerMaster != null)
			{
				var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
						.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

				MailSender sender = new MailSender(conferenceMailServerMaster.MailServer);
				MailAddress from = new MailAddress(conferenceMailServerMaster.Mail);
				MailAddress to = new MailAddress(conferenceMailServerMaster.Mail);

				List<Traffic> mailList = new List<Traffic>();
				var mailTraffic = new Traffic()
				{
					TrafficType = result.TrafficType,
					FlightDate = conferenceMaster.IsInternational ? result.FlightDate.ToString("MM/dd/yyyy HH:mm") : result.FlightDate.ToString("yyyy-MM-dd HH:mm"),
					FlightNum = result.FlightNum,
					TrafficName = trafficMaster.TrafficName
				};
				mailList.Add(mailTraffic);

				MailMessage message = Utility.GetMailContent(new MailModel
				{
					MailRemark = ConstValues.MailSubject.交通修改,
					Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn,
					ConferenceId = conferenceMaster.ID,
					OrderNum = result.OrderNum,
					TrafficStatus = conferenceMaster.IsInternational ? "Canceled" : "已取消",
					TrafficList = mailList
				});
				message.To.Add(to);

				if (!string.IsNullOrWhiteSpace(conferenceMailServerMaster.CcMail))
				{
					foreach (string cc in conferenceMailServerMaster.CcMail.Split(ConstValues.chrSemicolon))
					{
						if (!string.IsNullOrWhiteSpace(cc) && cc.Contains(ConstValues.chrAt))
						{
							message.Bcc.Add(new MailAddress(cc.Trim()));
						}
					}
				}

				var mailTask = Task.Run(() =>
				{
					sender.SendMail(from, message, conferenceMailServerMaster.Password);
				});
			}
			#endregion

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessCancel),
					JsonRequestBehavior.AllowGet);
		}
	}
}